﻿using Newtonsoft.Json;
using PLCSharp.CoreModel.Common;
using Prism.Mvvm;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace PLCSharp.Views.MotionController
{
    public class InterpolationGroup : BindableBase
    {
        #region 属性
        [Key]
        public Guid ID { get; set; } = Guid.NewGuid();
        public Guid RecipeID { get; set; }

        private string _Name;
        /// <summary>
        /// 点名称
        /// </summary>
        public string Name
        {
            get { return _Name; }
            set { SetProperty(ref _Name, value); }
        }

        private Axis _AxisX;
        [NotMapped]
        /// <summary>
        /// 
        /// </summary>
        public Axis AxisX
        {
            get { return _AxisX; }
            set
            {
                SetProperty(ref _AxisX, value);
                if (value != null)
                {

                    AxisXName = value.Name;
                    Params.AxisXNo = value.AxisNo;
                }
                else
                    AxisXName = string.Empty;

            }
        }
        private string _AxisXName;
        /// <summary>
        /// 
        /// </summary>
        public string AxisXName
        {
            get { return _AxisXName; }
            set { SetProperty(ref _AxisXName, value); }
        }
        private Axis _AxisY;
        [NotMapped]
        /// <summary>
        /// 
        /// </summary>
        public Axis AxisY
        {
            get { return _AxisY; }
            set
            {
                SetProperty(ref _AxisY, value);
                if (value != null)
                {

                    AxisYName = value.Name;
                    Params.AxisYNo = value.AxisNo;
                }
                else
                    AxisYName = string.Empty;
            }
        }
        private string _AxisYName;
        /// <summary>
        /// 
        /// </summary>
        public string AxisYName
        {
            get { return _AxisYName; }
            set { SetProperty(ref _AxisYName, value); }
        }


        [Column("Interpolations")]
        /// <summary>
        /// 
        /// </summary>
        public string SerializedInterpolations
        {
            get => JsonConvert.SerializeObject(Interpolations); // 自动序列化
            set
            {
                Interpolations = JsonConvert.DeserializeObject<ObservableCollection<Interpolation>>(value); // 自动反序列化
            }
        }

        private ObservableCollection<Interpolation> _Interpolations = [];
        [NotMapped]
        /// <summary>
        /// 
        /// </summary>
        public ObservableCollection<Interpolation> Interpolations
        {
            get { return _Interpolations; }
            set { SetProperty(ref _Interpolations, value); }
        }

        [Column("Params")]
        public string SerializedParams
        {
            get => JsonConvert.SerializeObject(Params); // 自动序列化
            set => Params = JsonConvert.DeserializeObject<InterpolationGroupParams>(value); // 自动反序列化
        }

        private InterpolationGroupParams _Params;
        [NotMapped]
        /// <summary>
        /// Comment
        /// </summary>
        public InterpolationGroupParams Params
        {
            get
            {
                _Params ??= new InterpolationGroupParams();

                return _Params;
            }
            set
            {
                SetProperty(ref _Params, value);
            }
        }
        public class InterpolationGroupParams : BindableBase
        {

            private string _Prompt;
            [JsonIgnore]
            /// <summary>
            /// 提示
            /// </summary>
            public string Prompt
            {
                get { return _Prompt; }
                set { SetProperty(ref _Prompt, value); }
            }


            private double _MinVelocity;
            /// <summary>
            /// 
            /// </summary>
            public double MinVelocity
            {
                get { return _MinVelocity; }
                set { SetProperty(ref _MinVelocity, value); }
            }

            private double _MaxVelocity = 1000;
            /// <summary>
            /// 
            /// </summary>
            public double MaxVelocity
            {
                get { return _MaxVelocity; }
                set { SetProperty(ref _MaxVelocity, value); }
            }

            private double _Acc = 0.1;
            /// <summary>
            /// 加速时间
            /// </summary>
            public double Acc
            {
                get { return _Acc; }
                set { SetProperty(ref _Acc, value); }
            }

            private double _Dec = 0.1;
            /// <summary>
            /// 
            /// </summary>
            public double Dec
            {
                get { return _Dec; }
                set { SetProperty(ref _Dec, value); }
            }

            private double _StopVelocity;
            /// <summary>
            /// 
            /// </summary>
            public double StopVelocity
            {
                get { return _StopVelocity; }
                set { SetProperty(ref _StopVelocity, value); }
            }
            private ushort _Coordinate;
            /// <summary>
            /// 坐标系
            /// </summary>
            public ushort Coordinate
            {
                get { return _Coordinate; }
                set { SetProperty(ref _Coordinate, value); }
            }

            private double _Ahead;
            /// <summary>
            /// 
            /// </summary>
            public double Ahead
            {
                get { return _Ahead; }
                set { SetProperty(ref _Ahead, value); }
            }

            [JsonIgnore]
            public ushort AxisXNo { get; set; }

            [JsonIgnore]
            public ushort AxisYNo { get; set; }


            private ushort _OutBit;
            /// <summary>
            /// 
            /// </summary>
            public ushort OutBit
            {
                get { return _OutBit; }
                set { SetProperty(ref _OutBit, value); }
            }
            private double _DelayValue;
            /// <summary>
            /// 
            /// </summary>
            public double DelayValue
            {
                get { return _DelayValue; }
                set { SetProperty(ref _DelayValue, value); }
            }
        }
        #endregion

        #region 方法
        private readonly FlowModel flowModel = new();
        public void Run()
        {
            switch (flowModel.Step)
            {
                case 1:

                    AxisX.Interpolations = [.. Interpolations];
                    AxisX.InterpolationGroupParams = Params;
                    AxisX.MotionFlow.Step = 31;
                    flowModel.Step++;
                    break;
                case 10:
                    if (AxisX.InterpolationDone)
                    {
                        flowModel.Step = 0;
                        flowModel.Done = true;
                    }

                    break;
            }

        }

        public bool Go()
        {
            flowModel.Done = false;

            if (AxisX == null || AxisY == null)
            {
                flowModel.Step = 0;
                return false;
            }
            if (Interpolations.Count < 1)
            {
                flowModel.Step = 0;
                return false;
            }
            flowModel.Step = 1;
            return true;
        }

        public bool IsDone()
        {
            return flowModel.Done;
        }

        public void Stop()
        {
            AxisX?.Stop();
            AxisY?.Stop();
            flowModel.Reset();

        }


        #endregion
    }


}
